package com.shutuo.callnummeiwei.core;

import android.app.Application;
import android.content.Intent;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.shutuo.callnummeiwei.data.Parser;



public class SocketManager {
    private static SocketManager instance;
    private static ChannelClient channelClient = null;
    private static ChannelServer channelServer = null;

    private static LocalBroadcastManager mLocalBroadcastManager = null;

    public SocketManager() {
    }

    public static SocketManager getInstance() {
        if (instance == null) {
            synchronized (SocketManager.class) {
                if (instance == null) {
                    instance = new SocketManager();
                }
            }
        }
        return instance;
    }

    /**
     * @param application
     * @throws Exception
     */
    public void init(Application application) throws Exception {
        if (application == null) {
            throw new Exception("application is null");
        }
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(application);
        //        L.setupLogger(new L.AndroidLog());
        //        ashy.earl.common.app.App.appOnCreate(application);
    }

    /**
     * registMsg  参数type    range[1001~1050] 是叫号消息类型
     */
    public SocketManager initClient() {
        channelClient = new ChannelClient(5);
        channelClient.registMsg(C.TYPE_CALLNUMBER, Parser.PARSER_STRING);
        channelClient.registMsg(C.TYPE_CALLNUMBER_QUEUE, Parser.PARSER_WAITMSGSTRING);
        channelClient.addClientHandler(new ClientListenerImpl());
        if (instance == null) {
            getInstance();
        }
        return instance;
    }

    /**
     * registMsg  参数type    range[1001~1050] 是叫号消息类型
     */
    public SocketManager initServer() {
        channelServer = new ChannelServer(5);
        channelServer.registMsg(C.TYPE_CALLNUMBER, Parser.PARSER_STRING);
        channelServer.registMsg(C.TYPE_CALLNUMBER_QUEUE, Parser.PARSER_WAITMSGSTRING);
        channelServer.addClientHandler(new ServerListenerImpl());
        if (instance == null) {
            getInstance();
        }
        return instance;
    }


    class ServerListenerImpl implements ChannelServer.ServerHandler {
        @Override
        public boolean onNewClientMsg(ChannelServer.ClientInfo clientInfo, int type, Object msg) {
            Log.d("lk", "[ServerListenerImpl] [onNewClientMsg] " + msg + "    type:" + type);
            if (mLocalBroadcastManager != null) {
                Intent intent = new Intent(C.SERVER_NEW_CLIENT_MSG);
                intent.putExtra("clientInfo", clientInfo.toString());
                intent.putExtra("type", type);
                intent.putExtra("msg", msg.toString());
                mLocalBroadcastManager.sendBroadcast(intent);
            }
            return false;
        }

        @Override
        public void onClientStateChanged(ChannelServer.ClientInfo clientInfo) {
            Log.d("lk", "[ServerListenerImpl] [onClientStateChanged] " + clientInfo.toString());
            if (mLocalBroadcastManager != null) {
                Intent intent = new Intent(C.SERVER_CLIENT_STATE_ACTION);
                intent.putExtra("clientInfo", clientInfo.toString());
                mLocalBroadcastManager.sendBroadcast(intent);
            }
        }

        @Override
        public void onServerStateChanged(boolean ready) {
            Log.d("lk", "[ServerListenerImpl] [onServerStateChanged] " + ready);
            if (mLocalBroadcastManager != null) {
                Intent intent = new Intent(C.SERVER_STATE_ACTION);
                intent.putExtra("data", ready);
                mLocalBroadcastManager.sendBroadcast(intent);
            }
        }

    }

    class ClientListenerImpl implements ChannelClient.ClientHandler {
        @Override
        public void onStateChanged() {
            Log.d("lk", "[SocketManager][ClientListenerImpl] [onStateChanged] ");
            if (mLocalBroadcastManager != null && channelClient != null) {
                Intent intent = new Intent(C.CLIENT_STATE_ACTION);
                intent.putExtra("data", channelClient.getState());
                mLocalBroadcastManager.sendBroadcast(intent);
            }
        }

        @Override
        public boolean onNewPacket(int type, Object msg) {
            Log.d("lk", "[SocketManager][ClientListenerImpl] [onNewPacket] " + msg);
            if (mLocalBroadcastManager != null) {
                Intent intent = new Intent(C.CLIENT_NEW_PACKAGE_ACTION);
                intent.putExtra("type", type);
                intent.putExtra("msg", msg.toString());
                mLocalBroadcastManager.sendBroadcast(intent);
            }
            return false;
        }
    }

    public void connect(String serverIp, int serverPort) {
        if (channelClient == null) {
            Log.d("lk", "[SocketManager][connect] socketClient is null");
        }
        channelClient.setup(serverIp, serverPort);
    }

    public void startServer(int port) {
        channelServer.setup(port);
    }

    public void sendMsgToServer(int type, Object msg) {
        if (channelClient == null) {
            Log.d("lk", "[SocketManager][sendMsgToServer] socketClient is null");
        }
        channelClient.sendMsgToServer(type, msg);
    }

    public void teardownClient() {
        if (channelClient == null) {
            Log.d("lk", "[SocketManager][teardown] socketClient is null");
        }
        channelClient.teardown();
    }

    public void teardownServer() {
        if (channelServer == null) {
            Log.d("lk", "[SocketManager][teardown] socketClient is null");
        }
        channelServer.teardown();
    }
}
